package test.yzx.pproject.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;


public class HomeCenterLayout extends FrameLayout{

    public HomeCenterLayout(Context context) {
        this(context, null);
    }
    public HomeCenterLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public HomeCenterLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        doTouch();
    }



    private final float scaleMaxValue = 1.11f;
    private final int fadeDuration = 150;
    private final int scaleOnceDuration = 350;
    private ObjectAnimator mFadeOutAnim;
    private ObjectAnimator mFadeInAnim;
    private ObjectAnimator mTouchScaleAnim;
    private boolean inOnceScaleAnim = false;
    private boolean canResponseTouchEvent = false;



    /* cancel touch anim */
    private void cancelTouchScaleAnim(){
        if(mTouchScaleAnim != null)
            mTouchScaleAnim.cancel();
        mTouchScaleAnim = null;
    }
    /* end fade in animtor */
    private void endFadeInAnim(){
        if(mFadeInAnim != null)
            mFadeInAnim.end();
        mFadeInAnim=null;
    }
    /* end fade in animtor */
    private void endFadeOutAnim(){
        if(mFadeOutAnim != null)
            mFadeOutAnim.end();
        mFadeOutAnim=null;
    }
    /* get showing child view */
    private View getShowingView(){
        for (int i = 0; i < getChildCount(); i++)
            if(getChildAt(i).getVisibility()==View.VISIBLE)
                return getChildAt(i);
        return null;
    }
    /* fade in target view */
    private void fadeIn(View target, final Runnable onEnd){
        endFadeInAnim();
        mFadeInAnim = ObjectAnimator.ofFloat(target, "alpha", 0f, 1f);
        mFadeInAnim.setDuration(fadeDuration);
        mFadeInAnim.addListener(new AnimatorListenerAdapter(){
            public void onAnimationEnd(Animator animation) {
                mFadeInAnim = null;
                if(onEnd != null) onEnd.run();
            }
        });
        mFadeInAnim.start();
    }
    /* fade out target view */
    private void fadeOut(View target, final Runnable onEnd){
        endFadeOutAnim();
        mFadeOutAnim = ObjectAnimator.ofFloat(target, "alpha", 1f, 0f);
        mFadeOutAnim.setDuration(fadeDuration);
        mFadeOutAnim.addListener(new AnimatorListenerAdapter(){
            public void onAnimationEnd(Animator animation) {
                mFadeOutAnim = null;
                if(onEnd != null) onEnd.run();
            }
        });
        mFadeOutAnim.start();
    }
    /* find  direct  child view */
    private View findSon(@SuppressWarnings("ResourceType") int id){
        for (int i = 0; i < getChildCount(); i++)
            if(getChildAt(i).getId() == id)
                return getChildAt(i);
        return null;
    }
    /* 执行一下自身scale弹跳一次的动画效果 */
    private void animScale(int delay){
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, scaleMaxValue, 1f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, scaleMaxValue, 1f);
        ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(this, scaleX, scaleY);
        anim.setDuration(scaleOnceDuration);
        anim.setStartDelay(delay);
        anim.addListener(new AnimatorListenerAdapter(){
            public void onAnimationEnd(Animator animation) {
                inOnceScaleAnim = false;
            }
        });
        anim.start();
        inOnceScaleAnim = true;
    }
    /* 处理touch事件 */
    private void doTouch(){
        setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                //在执行scale弹跳动画  or   外部设置了不响应touch事件
                if(inOnceScaleAnim || !canResponseTouchEvent) return false;
                //准备执行点击回调事件
                if(readyDoClick) return true;
                //
                switch (event.getActionMasked()){
                    case MotionEvent.ACTION_DOWN:
                        doDownTouchAnim(false);
                        break;
                    case MotionEvent.ACTION_UP:
                        //判断是否为click事件依据: 手指是否在View的范围内
                        boolean xInScope = event.getX() > 0 && event.getX() < getWidth();
                        boolean yInScope = event.getY() > 0 && event.getY() < getHeight();
                        doUpTouchAnim(xInScope && yInScope);
                        break;
                }
                return true;
            }
        });
    }
    /* finger down , scale big */
    private void doDownTouchAnim(boolean relative){
        cancelTouchScaleAnim();
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", relative?getScaleX():1f, scaleMaxValue);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", relative?getScaleY():1f, scaleMaxValue);
        mTouchScaleAnim =  ObjectAnimator.ofPropertyValuesHolder(this, scaleX, scaleY);
        mTouchScaleAnim.setDuration(touchDownAnimDuration);
        mTouchScaleAnim.setInterpolator(new DecelerateInterpolator());
        mTouchScaleAnim.addListener(new AnimatorListenerAdapter(){
            public void onAnimationEnd(Animator animation) {
                mTouchScaleAnim = null;
            }
        });
        mTouchScaleAnim.start();
    }
    /* finger up , scale back */
    private void doUpTouchAnim(boolean isClick){
        final Runnable run = new Runnable(){
            public void run() {
                PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", scaleMaxValue, 0.75f, 1.03f, 1f);
                PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", scaleMaxValue, 0.75f, 1.03f, 1f);
                mTouchScaleAnim = ObjectAnimator.ofPropertyValuesHolder(HomeCenterLayout.this, scaleX, scaleY);
                mTouchScaleAnim.setDuration(270);
                mTouchScaleAnim.addListener(new AnimatorListenerAdapter(){
                    public void onAnimationEnd(Animator animation) {
                        mTouchScaleAnim = null;
                        if(readyDoClick){
                            readyDoClick = false;
                            if(mClickListener==null)
                                return;
                            mClickListener.onClick(HomeCenterLayout.this);
                        }
                    }
                });
                mTouchScaleAnim.start();
            }
        };
        if(!isClick) {
            cancelTouchScaleAnim();
            readyDoClick = false;
            run.run();
        } else{
            // 将即将执行点击事件标记置true, 阻止touch事件触发
            readyDoClick = true;
            /// 执行个快速的动画将down动画补全 ///
            int hasAnimDuration = mTouchScaleAnim==null ? touchDownAnimDuration : (int)mTouchScaleAnim.getCurrentPlayTime();
            int leftTime = touchDownAnimDuration - hasAnimDuration;
            cancelTouchScaleAnim();
            PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", getScaleX(), scaleMaxValue);
            PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", getScaleY(), scaleMaxValue);
            ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(HomeCenterLayout.this, scaleX, scaleY);
            anim.setDuration(leftTime <100 ? leftTime:100);
            anim.addListener(new AnimatorListenerAdapter(){
                public void onAnimationEnd(Animator animation) {
                    run.run();
                }
            });
            anim.start();
        }
    }


    private boolean readyDoClick = false;
    private OnClickListener mClickListener;
    private final int touchDownAnimDuration = 300;



    @Override
    public void setOnClickListener(OnClickListener l) {
        mClickListener = l;
    }
    /** {@link #showView(int, boolean)} */
    public void showView(View view, boolean animScale){
        showView(view.getId(), animScale);
    }
    /** {@link #showView(int) } */
    public void showView(View view){
        showView(view.getId());
    }
    /** 显示指定id的View隐藏其他, 不经过动画 */
    public void showView(@SuppressWarnings("ResourceType") int id){
        endFadeOutAnim();
        endFadeInAnim();
        View target = findSon(id);
        if(target==null) return ;
        for (int i = 0; i < getChildCount(); i++)
                getChildAt(i).setVisibility(View.GONE);
        target.setAlpha(1f);
        target.setVisibility(View.VISIBLE);
    }
    /** 显示指定id的view, 会使用alpha动画切换View
     * @param animScale  是否执行自身scale的弹跳动画
     */
    public void showView(@SuppressWarnings("ResourceType") int id, boolean animScale){
        if(animScale)
            animScale(fadeDuration);
        final View target = findSon(id);
        if(target == null) return ;
        endFadeOutAnim();
        endFadeInAnim();
        final View showingView = getShowingView();
        if(showingView==null){
            showView(id);
            return ;
        }
        // fade out showing view
        fadeOut(showingView, new Runnable() {
            public void run() {
               showingView.setVisibility(View.GONE);
                //fade in target view
                target.setVisibility(View.VISIBLE);
                fadeIn(target, new Runnable() {
                    public void run() {
                    }
                });
            }
        });
    }
    /** 是否可以响应touch事件 */
    public void setCanResponseClickEvent(boolean canResponseClickEvent) {
        this.canResponseTouchEvent = canResponseClickEvent;
    }

}
